package com.terrapages.wmsc4j.layer.profiles;

import java.awt.Dimension;
import java.io.File;
import java.io.IOException;

import com.terrapages.wmsc4j.bean.BBox;
import com.terrapages.wmsc4j.cache.Cache;
import com.terrapages.wmsc4j.layer.StaticLayer;
import com.terrapages.wmsc4j.layer.WMSLayer;
import com.terrapages.wmsc4j.layer.WMSMetaLayer;
import com.terrapages.wmsc4j.layer.resolution.Resolution;
import com.terrapages.wmsc4j.layer.resolution.ResolutionSet;
import com.terrapages.wmsc4j.layer.tile.ImageMimeType;
import com.terrapages.wmsc4j.layer.tile.TileFormat;
import com.terrapages.wmsc4j.wms.WMSService;

/**
 * Makes creating the "regular" layers easy based on their profiles.
 * Provides methods for creating {@link StaticLayer}s, {@link WMSLayer}s, and {@link WMSMetaLayer}s.
 * See the following link for more information...
 * http://wiki.osgeo.org/index.php/WMS_Tiling_Client_Recommendation#Global_Profiles
 */
public enum GlobalProfile 
{
	//makes Unprojected Layers
	UNPROJECTED(
			new Resolution(0.703125),
			new BBox(-180, -90, 180, 90),
			new Dimension(256,256)),
	//makes Mercator Layers
	MERCATOR(
			new Resolution(156543.03390625),
			new BBox(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
			new Dimension(256,256));
	
	private Resolution topResolution;
	private BBox coverage;
	private Dimension tileSize;
	
	/**
	 * Gathers the relevent information common to all profiles 
	 * @param topResolution The first resolution from which to base others
	 * @param coverage The coverage of the layer
	 * @param tileSize The size of the tiles
	 */
	private GlobalProfile(Resolution topResolution, BBox coverage, Dimension tileSize) 
	{
		this.topResolution = topResolution;
		this.coverage = coverage;
		this.tileSize = tileSize;
	}
	
	/**
	 * Makes a {@link StaticLayer} 
	 * using the given cache 
	 * with the given number of resolutions,
	 * the given image Type
	 * and the given name of the title.
	 * 
	 * @param cache
	 * @param numResolutions
	 * @param imageType
	 * @param title
	 * @return
	 */
	public StaticLayer makeStaticLayer(Cache cache, int numResolutions, ImageMimeType imageType, String title)
	{
		return new StaticLayer(   
				cache,
				new ResolutionSet(topResolution, numResolutions),
				new TileFormat (tileSize, imageType),
				coverage,
				coverage.getMinPos(),
				title
		);
	}
	
	/**
	 * Makes a {@link StaticLayer} 
	 * using the given cache 
	 * with the given number of resolutions,
	 * the given image Type
	 * the given name of the title
	 * and using the image of the given file when the tile could not be found in cache.
	 * 
	 * @param staticImage image to use when the tile could not be found in cache
	 * @param cache
	 * @param numResolutions
	 * @param imageType
	 * @param title
	 * @return
	 * @throws IOException
	 */
	public StaticLayer makeStaticLayer(File staticImage,Cache cache, int numResolutions, ImageMimeType imageType, String title) throws IOException
	{
		return new StaticLayer( 
				staticImage,
				cache,
				new ResolutionSet(topResolution, numResolutions),
				new TileFormat (tileSize, imageType),
				coverage,
				coverage.getMinPos(),
				title
		);
	}
	
	/**
	 * Makes a {@link WMSLayer} 
	 * using the given cache 
	 * with the given number of resolutions,
	 * the given image Type
	 * the given name of the title
	 * and using the WMSService to seed when the tile could not be found in cache.
	 * 
	 * @param wmsService WMSService to use to seed when the tile could not be found in cache.
	 * @param cache
	 * @param numResolutions
	 * @param imageType
	 * @param title
	 * @return
	 * @throws IOException
	 */
	public WMSLayer makeWMSLayer(WMSService wmsService, Cache cache, int numResolutions, ImageMimeType imageType, String title)
	{
		return new WMSLayer(
				wmsService,
				cache,
				new ResolutionSet(topResolution, numResolutions),
				new TileFormat (tileSize, imageType),
				coverage,
				coverage.getMinPos(),
				title
		);
	}
	
	/**
	 * Makes a {@link WMSMetaLayer} 
	 * using the given cache 
	 * with the given number of resolutions,
	 * the given image Type
	 * the given name of the title
	 * and using the WMSService to seed when the tile could not be found in cache
	 * using a meta-tiling multiplicity.
	 * 
	 * @param multiplicity 1 = no meta-tiling, 2 = 4 tiles in one meta tile, 3 = 9 tiles in one meta tile, n = n^2 tiles in one meta tile
	 * @param wmsService WMSService to use to seed when the tile could not be found in cache.
	 * @param cache
	 * @param numResolutions
	 * @param imageType
	 * @param title
	 * @return
	 * @throws IOException
	 */
	public WMSMetaLayer makeWMSMetaLayer(int multiplicity, WMSService wmsService, Cache cache, int numResolutions, ImageMimeType imageType, String title)
	{
		return new WMSMetaLayer(
				multiplicity,
				wmsService,
				cache,
				new ResolutionSet(topResolution, numResolutions),
				new TileFormat (tileSize, imageType),
				coverage,
				coverage.getMinPos(),
				title
		);
	}
}
